home *** CD-ROM | disk | FTP | other *** search
- ; Help.asm
- ; Resident help facility
- ; Format: HELP filespec [... filespec][/Nn][/P][/Hn] | [/U]
- ; defaults: pages = 4; hot key = Alt H
-
- CODE SEGMENT ;********************************;
- ASSUME CS:CODE,DS:CODE ;* *;
- ORG 100H ;* Requires MASM 2.0 or later *;
- ;* Remember to EXE2BIN *;
- START: JMP BEGINNING ;* *;
- ;********************************;
-
- ; DATA AREA
- ; ---------
- COPYRIGHT DB "HELP 1.0 (c) 1987 Ziff Communications Co.",13,10
- DB "Successfully installed",13,10
- ALT_COMBO DB "Press Alt H to activate",10,0,26
-
- PROGRAMMER DB "Michael J. Mefford"
-
- OLD_KEYBOARD DD ?
- CRT_COLS DW ?
- STATUS_REG DW ?
- SCREEN_SEG DW 0B000H
- LINE_COUNT DB 25
- IMMEDIATE_FLAG DB 0
- BUSY DB 0
-
- IMMEDIATE DW POP_IT
- DATA_SEG DW ?
- DATA_INT DB 0
- INSTALLED_FLAG DB 0
- POPUP_FLAG DB 0
- HOT_KEY DB 35
-
- FILENAME DW ?
- ERROR_LEVEL DB 0
-
- CURRENT_PAGE DB 1
- RESERVED_PAGES DB 4
- ACTIVE_PAGES DB 0
- PAGE_COUNT DB 0
- DELIMITERS DB 9,32,13,44,";","/"
-
- SYNTAX LABEL BYTE
- DB 10,"Usage: HELP filespec [... filespec][/Nn][/Hn][/P] | [/U]",13,10,10
- DB "/Nn where n = number of reserved pages (1-14); default = 4",13,10
- DB "/Hn where n = Alt hot key combo (A-Z,0-9,",34,45,34,44,34,61,34
- DB "); default = H",13,10
- DB "/P = immediate pop-up",13,10
- DB "/U = uninstall",13,10,10
- DB "Use: PgUp PgDn Home End to navigate through HELP",13,10
- DB 5 DUP(32),"ESC or hot key to exit",10,0
-
-
- ACTIVE_MSG DB " active page(s)",13,10,0
- RESERVED_MSG DB " total page(s)",13,10,10,0
- UNLOAD_MSG DB 10,"HELP can't be uninstalled.",13,10
- DB "Uninstall resident programs in reverse order.",10,0
- UNINSTALL_MSG DB 10,"HELP uninstalled",10,0
- NO_FREE DB "Too many resident programs",0
- NOT_FOUND DB 32,"not found",13,10,0
- NOT_ENOUGH DB "Not enough memory",0
- ALLOCATE_MSG DB "Memory allocation error",13,10,0
-
- SCAN_CODES LABEL BYTE
-
- DB 45,130,48,129,49,120,50,121,51,122,52,123,53,124
- DB 54,125,55,126,56,127,57,128,61,131,65,30,66,48,67
- DB 46,68,32,69,18,70,33,71,34,72,35,73,23,74,36,75,37
- DB 76,38,77,50,78,49,79,24,80,25,81,16,82,19,83,31
- DB 84,20,85,22,86,47,87,17,88,45,89,21,90,44
-
- ; SCAN CODES FOR ALT COMBO
- ;
- ; Code Key Code Key Code Key Code Key
- ; 16 Q 30 A 44 Z 120 1
- ; 17 W 31 S 45 X 121 2
- ; 18 E 32 D 46 C 122 3
- ; 19 R 33 F 47 V 123 4
- ; 20 T 34 G 48 B 124 5
- ; 21 Y 35 H 49 N 125 6
- ; 22 U 36 J 50 M 126 7
- ; 23 I 37 K 127 8
- ; 24 O 38 L 128 9
- ; 25 P 129 0
- ; 130 -
- ; Default is 35 (Alt H) 131 =
-
-
- ;************* KEYBOARD INTERCEPTOR *************;
-
- NEW_KEYBOARD: STI
- PUSHF ;Simulate an interrupt
- CALL CS:OLD_KEYBOARD ; by pushing flags and far call.
-
- POP_IT: PUSHF ;On return save all registers
- PUSH DS ; that will be used.
- PUSH ES
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DI
- PUSH BP
-
- PUSH CS ;Point to our data.
- POP DS
- CLD ;Moves in forward direction.
- MOV AX,40H ;Point to ROM BIOS data area
- MOV ES,AX
- MOV AX,ES:[4AH] ;Get number of columns on screen
- MOV CRT_COLS,AX ; and store.
- MOV AX,ES:[63H] ;Get base address of video card.
- ADD AX,6 ;Convert to status register
- MOV STATUS_REG,AX ; and store.
- CMP AX,3BAH ;Is it mono card?
- JZ MONO ;If yes, use b800h.
- MOV SCREEN_SEG,0B800H ; else point to color card.
- MONO: MOV AL,ES:[49H] ;Retrieve video mode.
- CMP AL,3 ;Is it text mode?
- JBE GOOD_MODE ;If yes, OK.
- CMP AL,7
- JNZ DONE_HERE ;Exit if graphics
-
- GOOD_MODE: CMP IMMEDIATE_FLAG,1 ;Is there a pop-up request?
- JZ NOW ;If yes, pop-up right now.
- CMP BUSY,1 ;If the window is already popped
- JZ DONE_HERE ; exit Int 9 back to window.
- MOV AH,1 ;Is an ASCII character ready?
- INT 16H
- JZ DONE_HERE ;If it's just a key release, exit.
- CMP AL,0 ;Is it extended code?
- JNZ DONE_HERE ;If no, exit.
- CMP AH,HOT_KEY ;Else, see if our Alt key combo.
- JZ OPEN_WINDOW ;If yes, open window
- DONE_HERE: JMP SHORT EXIT_KEYBOARD ; else exit.
-
- ;------------------------------------;
- ; Save screen so we can pop up HELP. ;
- ;------------------------------------;
-
- OPEN_WINDOW: MOV AH,0 ;Retrieve and discard hot key
- INT 16H ; character from keyboard buffer.
- NOW: MOV BUSY,1 ;Flag that window is open.
- MOV IMMEDIATE_FLAG,0 ;Restore immediate flag.
- CALL STORE_SCREEN ;Store screen.
-
- ;-----------------------------------------;
- ; Loop here looking for valid keystrokes. ;
- ;-----------------------------------------;
-
- READ_KEY: MOV CL,CURRENT_PAGE ;Get current page.
- DEC CL ;Adjust for starting offset.
- CALL PAGE_SIZE ;Get offset.
- MOV SI,DX
- CALL WRITE_SCREEN ;Update the screen.
- MOV AH,0 ;Wait for a character.
- INT 16H
- CMP AH,1 ;Is it Esc?
- JZ EXIT_WINDOW ;If yes, exit window.
- CMP AH,BYTE PTR HOT_KEY ;Is it our key combo?
- JZ EXIT_WINDOW ;If yes, exit window.
-
- MOV CL,CURRENT_PAGE ;Get current page.
- CMP AH,49H ;Is it PgUp?
- JNZ CK_PGDN
- CMP CL,1 ;If yes, is it already page one?
- JZ END_KEY
- DEC CL ;If no, decrement page.
-
- CK_PGDN: CMP AH,51H ;Is it PgDn?
- JNZ CK_HOME
- CMP CL,ACTIVE_PAGES ;If yes, are we already last page?
- JZ END_KEY
- INC CL ;If no, increment page.
-
- CK_HOME: CMP AH,47H ;Is it Home?
- JNZ CK_END
- MOV CL,1 ;If yes, move to page one.
-
- CK_END: CMP AH,4FH ;Is it End?
- JNZ END_KEY
- MOV CL,ACTIVE_PAGES ;If yes, move to last page.
-
- END_KEY: MOV CURRENT_PAGE,CL ;Store new current page.
- JMP SHORT READ_KEY
-
- ;----------------------------------;
- ; This is the window exit routine. ;
- ;----------------------------------;
-
- EXIT_WINDOW: MOV SI,OFFSET SCREEN_BUFFER ;Point to the stored screen
- CALL WRITE_SCREEN ; and restore the screen.
- MOV IMMEDIATE_FLAG,0 ;Reset the pop-up flag.
- MOV BUSY,0 ;Flag done with window.
-
- EXIT_KEYBOARD: POP BP ;Restore all registers.
- POP DI
- POP SI
- POP DX
- POP CX
- POP BX
- POP AX
- POP ES
- POP DS
- POPF
- IRET ;Return from interrupt.
-
-
- ;************* FILE LOADING AND INSTALL PROCEDURE *************;
-
- BEGINNING: CLD
- PUSH CS
- POP DATA_SEG ;Store our segment.
- CMP SP,65533 ;Do we have 64K?
- JA CK_PARA
- MOV SI,OFFSET NOT_ENOUGH ;If no, exit with message.
- JMP ERROR_EXIT
-
- CK_PARA: CMP BYTE PTR DS:[80H],0 ;Any parameters?
- JNZ CK_FREE
- OPTIONS: MOV SI,OFFSET SYNTAX ;If no, exit with syntax message.
- JMP ERROR_EXIT
-
- ;----------------------------------------------------------------------;
- ; Check user vectors to see if we are installed or if one is available ;
- ;----------------------------------------------------------------------;
-
- CK_FREE: MOV AL,60H - 1 ;Available vectors are 60H - 67H.
- FREE_USER_INT: INC AL
- MOV AH,35H ;Get vector address.
- INT 21H
- CMP BX,0 ;Is offset being used?
- JNZ CK_SIGNATURE ;If yes, see if it's us.
- MOV DX,ES
- CMP DX,0 ;Is segment being used?
- JNZ CK_SIGNATURE ;If yes, see if it's us.
- MOV DATA_INT,AL ;If available, save INT number.
-
- NEXT_USER: CMP AL,67H ;Have we checked all 7?
- JNZ FREE_USER_INT ;If no, next one.
- JMP SHORT CK_SWITCHES
-
- CK_SIGNATURE: MOV DI,BX ;See if INT has our signature.
- MOV SI,100H
- MOV CX,30/2
- REPZ CMPSW
- JNZ NEXT_USER ;If yes, already installed.
- MOV DATA_SEG,ES ;Save segment.
- MOV INSTALLED_FLAG,1
-
- ;--------------------------------------------;
- ; Check the command line for switch options. ;
- ;--------------------------------------------;
-
- CK_SWITCHES: PUSH DATA_SEG ;First point to installed segment.
- POP ES
- MOV SI,81H ;First parameter.
-
- NEXT_SWITCH: LODSB ;Get a byte.
- CMP AL,13 ;Is it carriage return?
- JZ CK_FILENAMES ;If yes, done here.
- CMP AL,"/" ;Is it switch character?
- JNZ NEXT_SWITCH ;If no, get next byte
- LODSB ; else get switch.
- CMP AL,13 ;Is it carriage return?
- JZ CK_FILENAMES ;If yes, done here
- CALL CAPITALIZE ; else capitalize.
-
- CMP AL,"U" ;Is it "U"?
- JNZ CK_N
- CMP INSTALLED_FLAG,1 ;If yes, are we installed?
- JNZ NEXT_SWITCH
- JMP UNINSTALL ;If yes, uninstall.
-
- CK_N: CMP AL,"N" ;Is it "N"?
- JNZ CK_P
- CMP INSTALLED_FLAG,1 ;If yes, are we installed?
- JZ NEXT_SWITCH ;If yes, can't change reserved.
- CALL DEC_TO_HEX ;Else, convert decimal to hex.
- CMP BL,14 ;Request greater than 14 pages
- JA NEXT_SWITCH ; or equal to zero?
- CMP BL,0
- JZ NEXT_SWITCH ;If yes, ignore.
- MOV RESERVED_PAGES,BL ;Else, store reserved pages.
- JMP SHORT NEXT_SWITCH
-
- CK_P: CMP AL,"P" ;Is it "P"?
- JNZ CK_H
- MOV POPUP_FLAG,1 ;If yes, flag to pop-up immediate.
-
- CK_H: CMP AL,"H" ;Is it "H"?
- JNZ NEXT_SWITCH
- LODSB
- DEC SI ;Adjust in case it's just CR.
- CALL CAPITALIZE
- MOV DI,OFFSET SCAN_CODES
- MOV CX,38 ;38 possible Alt key combos.
-
- NEXT_ALT: SCASB ;Do we have a match?
- JZ GOT_ALT
- INC DI ;If no, bump pointer to next byte.
- LOOP NEXT_ALT
- JMP SHORT NEXT_SWITCH
-
- GOT_ALT: MOV ALT_COMBO + 10,AL ;Store Alt key.
- MOV AL,[DI] ;Get scan code
- MOV ES:HOT_KEY,AL ; and store.
- JMP SHORT NEXT_SWITCH
-
- ;-----------------------------------------------------;
- ; This routine parses the command line for filenames. ;
- ;-----------------------------------------------------;
-
- CK_FILENAMES: MOV SI,81H ;Point to first parameter.
- NEXT_FILENAME: CALL CK_DELIMITER ;Is it a delimiter?
- JC CK_CR ;If yes, see if end.
- MOV FILENAME,SI ;Else, store filename start.
- FIND_END: CALL CK_DELIMITER ;Look for delimiter to mark end.
- JNC FIND_END
- PUSH SI ;Save pointer and delimiter.
- PUSH AX
- CALL READ_FILE ;Read the file in.
- POP AX
- POP SI ;Restore pointers.
-
- CK_CR: CMP AL,13 ;Is it carriage return?
- JZ END_FILENAMES ;If yes, done here.
- CMP AL,"/" ;Is it switch character?
- JNZ NEXT_FILENAME ;If no, get next filename.
- FIND_SWITCH: CALL CK_DELIMITER ;Else, look for delimiter.
- JNC FIND_SWITCH
- JMP SHORT CK_CR ;And check if carriage return.
-
- END_FILENAMES: MOV AL,PAGE_COUNT ;Retrieve page count.
- CMP INSTALLED_FLAG,1 ;Are we installed?
- JZ STORE_ACTIVE ;If yes, check pages read.
- CMP AL,RESERVED_PAGES ;Pages read greater than reserved?
- JBE STORE_ACTIVE
- MOV RESERVED_PAGES,AL ;If yes, store as reserved.
-
- STORE_ACTIVE: CMP AL,0 ;Did we read any pages?
- JZ CK_INSTALLED1 ;If no, check if installed.
- MOV ES:ACTIVE_PAGES,AL ;Else, store active pages.
- MOV ES:CURRENT_PAGE,1 ;Reset the current page to one.
- JMP SHORT CK_POPUP ;Check popup request.
-
- CK_INSTALLED1: CMP INSTALLED_FLAG,1 ;Are we installed?
- JNZ CK_INSTALLED2 ;If no, exit.
-
- ;----------------------------------------;
- ; This routine does an immediate pop-up. ;
- ;----------------------------------------;
-
- CK_POPUP: CMP POPUP_FLAG,1 ;Is there a popup request?
- JNZ CK_INSTALLED2 ;If no, check pages read.
- MOV ES:IMMEDIATE_FLAG,1 ;Else, flag keyboard routine.
- PUSHF ;Simulate an interrupt.
- CALL DWORD PTR IMMEDIATE
- MOV BL,0 ;Error level of zero.
- CMP AL,0 ;Any pages read?
- JZ EXIT ;If no, done here.
-
- ;--------------------------------------------------;
- ; This routine checks to see if we are to install. ;
- ;--------------------------------------------------;
-
- CK_INSTALLED2: CMP AL,0 ;Did we fail to open a file?
- MOV SI,OFFSET SYNTAX ;If yes, exit with syntax message.
- JZ ERROR_EXIT
- PUSH AX
- MOV CL,AL ;Save active pages.
- MOV DL,10
- CALL WRITE_IT ;Display linefeed.
- CALL WRITE_NUMBER ;Display active pages.
- MOV SI,OFFSET ACTIVE_MSG
- CALL DISPLAY_TEXT
- POP AX
-
- CMP INSTALLED_FLAG,1 ;Are we already installed?
- MOV BL,ERROR_LEVEL
- JZ EXIT ;If yes, done here
- CK_INT: CMP DATA_INT,0 ;Did we find a free user interrupt?
- JNZ INSTALL ;If yes, install
- MOV SI,OFFSET NO_FREE ;Else, exit with message.
-
- ;-------------------;
- ; This is the exit. ;
- ;-------------------;
-
- ERROR_EXIT: MOV BL,1 ;Error code of one.
- MSG_EXIT: CALL DISPLAY_TEXT
- EXIT: MOV AL,BL
- MOV AH,4CH ;Return with error code.
- INT 21H ;Terminate.
-
- ;--------------------------------;
- ; This is the install procedure. ;
- ;--------------------------------;
-
- INSTALL: MOV AX,DS:[2CH] ;Get environment segment.
- MOV ES,AX
- MOV AH,49H ;Free up environment.
- INT 21H
- MOV SI,OFFSET ALLOCATE_MSG
- JC ERROR_EXIT ;If error, exit with message.
-
- MOV DX,100H ;Install user interrupt as
- MOV AL,DATA_INT ; pointer to residency.
- MOV AH,25H
- INT 21H
-
- MOV AX,3509H ;Get keyboard interrupt.
- INT 21H
- MOV WORD PTR OLD_KEYBOARD,BX ;Save old interrupt.
- MOV WORD PTR OLD_KEYBOARD[2],ES
-
- MOV DX,OFFSET NEW_KEYBOARD ;Install new interrupt.
- MOV AX,2509H
- INT 21H
-
- MOV CL,RESERVED_PAGES ;Display reserved pages.
- CALL WRITE_NUMBER
- MOV SI,OFFSET RESERVED_MSG
- CALL DISPLAY_TEXT
-
- MOV SI,OFFSET COPYRIGHT ;Display install message.
- CALL DISPLAY_TEXT
-
- CALL PAGE_SIZE ;Convert reserved pages to offset.
- MOV CL,4
- SHR DX,CL ;Convert to paragraphs.
- INC DX ;Round up one.
- MOV AX,3100H ;Return error code of zero.
- INT 21H ;Terminate but stay resident.
-
- ;*************;
- ; SUBROUTINES ;
- ;*************;
-
- ;-----------------------------------------------;
- ; This subroutine uninstalls the resident help. ;
- ;-----------------------------------------------;
-
- UNINSTALL: MOV AX,3509H ;Get keyboard interrupt.
- INT 21H
- CMP BX,OFFSET NEW_KEYBOARD ;Is the offset vector same?
- MOV SI,OFFSET UNLOAD_MSG ;Error message if INT 9h changed.
- MOV BL,1 ;Error code of one if fails.
- JNZ MSG_EXIT
- MOV AX,ES ;Is segment vector same?
- CMP AX,DATA_SEG
- JNZ MSG_EXIT ;If no, exit with error.
-
- MOV ES,DATA_SEG ;Point to resident segment.
- MOV AH,49H ;And return memory to system pool.
- INT 21H
- MOV SI,OFFSET ALLOCATE_MSG
- JNC DEALLOCATED ;Display message if problem.
- CALL DISPLAY_TEXT
-
- DEALLOCATED: MOV DX,ES:WORD PTR OLD_KEYBOARD ;Restore old INT 9.
- MOV DS,ES:WORD PTR OLD_KEYBOARD[2]
- MOV AX,2509H
- INT 21H
-
- MOV AL,ES:DATA_INT ;Retrieve user interrupt.
- XOR DX,DX
- MOV DS,DX ;Return vector to nulls.
- MOV AH,25H
- INT 21H
-
- PUSH CS
- POP DS
- MOV SI,OFFSET UNINSTALL_MSG ;Display uninstall message.
- MOV BL,0 ;Error code of zero.
- JMP MSG_EXIT ;And exit.
-
- ;-----------------------------------------;
- ; These subroutines display the messages. ;
- ;-----------------------------------------;
-
- WRITE_NUMBER: MOV BL,CL ;Retrieve number.
- CMP BL,10 ;Is it greater than ten?
- JB ONES
- MOV DL,"1" ;If yes, display a one.
- CALL WRITE_IT
- SUB BL,10
- ONES: MOV DL,BL
- ADD DL,"0" ;Convert to decimal.
- CALL WRITE_IT ;Display one's digit.
- RET
-
- ;----------------------------------------;
-
- WRITE_IT: MOV AH,2 ;Display byte via DOS.
- INT 21H
- RET
-
- ;----------------------------------------;
-
- DISPLAY_IT: CALL WRITE_IT
- DISPLAY_TEXT: LODSB ;Get a byte
- MOV DL,AL
- CMP DL,0 ;Zero marks end of string.
- JNZ DISPLAY_IT
- RET
-
- ;-------------------------------------------------------------;
- ; This subroutine opens files if there is room to store them. ;
- ;-------------------------------------------------------------;
-
- READ_FILE: CALL CK_SPACE ;Is there room for help?
- JC END_READ
- MOV DX,FILENAME ;If yes, open file.
- DEC DX
- MOV AX,3D00H
- INT 21H
- JNC GOT_FILE
- MOV ERROR_LEVEL,1 ;Else, indicate had a problem.
- MOV SI,DX ;Display filename and message
- CALL DISPLAY_TEXT ; if file not found.
- MOV SI,OFFSET NOT_FOUND
- CALL DISPLAY_TEXT
- RET
-
- GOT_FILE: MOV BX,AX ;Filehandle in BX.
- NEXT_READ: CALL READ_IT ;Read it.
- JC CLOSE_FILE ;Done here if nothing read.
- CALL CK_SPACE ;If room, read balance, if any,
- JNC NEXT_READ ; into next page.
-
- CLOSE_FILE: MOV AH,3EH ;Close file.
- INT 21H
- END_READ: RET
-
- ;--------------------------------------------------------------------;
- ; This subroutine does the actual reading of help files into storage ;
- ;--------------------------------------------------------------------;
-
- READ_IT: MOV CL,PAGE_COUNT ;Retrieve page count.
- CALL PAGE_SIZE ;Convert to offset.
- PUSH ES
- POP DS ;Point to storage segment.
- MOV CX,4000 ;Read 4000 bytes.
- MOV AH,3FH
- INT 21H
- JC READ_END
- CMP AX,0 ;Did we read anything?
- JZ READ_END
- INC CS:PAGE_COUNT ;If yes, increment page count.
- SUB CX,AX ;Was it a full page?
- JZ SKIP_PAD
- MOV DI,DX ;If no, pad balance with nulls.
- ADD DI,AX
- XOR AL,AL
- REP STOSB
- SKIP_PAD: CLC ;Indicate read something.
- JMP SHORT RESTORE_DS
-
- READ_END: STC ;Indicate nothing read.
- RESTORE_DS: PUSH CS ;Restore data segment.
- POP DS
- RET
-
- ;------------------------------------------------;
- ; This subroutine checks for free storage space. ;
- ;------------------------------------------------;
-
- CK_SPACE: CMP PAGE_COUNT,14 ;Already a full 14 pages?
- JZ NO_SPACE ;If yes, no space.
- CMP INSTALLED_FLAG,1 ;Are we installed.
- JNZ SPACE
- MOV AL,ES:RESERVED_PAGES ;If yes, are reserved pages full?
- CMP AL,PAGE_COUNT
- JZ NO_SPACE ;If yes, no space.
- SPACE: CLC ;Else, there is space.
- RET
-
- NO_SPACE: STC
- RET
-
- ;-------------------------------------------------------;
- ; This subroutine calculates the page offsets. ;
- ; Enter with CL = multiplicand; Return with DX = offset ;
- ;-------------------------------------------------------;
-
- PAGE_SIZE: MOV AX,4000 ;Multiply by 4000 bytes.
- XOR DX,DX
- XOR CH,CH
- MUL CX
- MOV DX,OFFSET PAGE_BUFFER ;Add to page buffer offset.
- ADD DX,AX
- RET
-
- ;------------------------------------------;
- ; This subroutine converts decimal to hex. ;
- ;------------------------------------------;
-
- DEC_TO_HEX: XOR BL,BL ;Start with zero.
- NEXT_NUMBER: LODSB ;Get a byte.
- CMP AL,"0" ;Is it a number?
- JB END_NUMBER
- CMP AL,"9"
- JA END_NUMBER
- SUB AL,"0" ;If yes convert to hex.
- XCHG AL,BL ;Save it.
- XOR AH,AH ;Multiply previous by 10.
- MOV DL,10
- MUL DL
- XCHG AL,BL ;Retrieve current number.
- ADD BL,AL ;And add to total.
- JMP SHORT NEXT_NUMBER
- END_NUMBER: DEC SI ;Adjust pointer.
- RET
-
- ;---------------------------------------------------------;
- ; This subroutine checks the command line for delimiters. ;
- ;---------------------------------------------------------;
-
- CK_DELIMITER: LODSB ;Get a byte.
- MOV DI,OFFSET DELIMITERS ;Point to delimiters.
- MOV CX,6
- REPNZ SCASB ;And see if match.
- JNZ NO_DELIMITER
- MOV BYTE PTR [SI-1],0 ;If yes, convert to ASCIIZ.
- STC
- RET
- NO_DELIMITER: CLC
- RET
-
- ;-------------------------------------------------;
- ; This subroutine capitalizes the character in AL ;
- ;-------------------------------------------------;
-
- CAPITALIZE: CMP AL,"a"
- JB END_CAPS
- CMP AL,"z"
- JA END_CAPS
- AND AL,5FH
- END_CAPS: RET
-
- ;------------------------------------------------------------------;
- ; This subroutine stores the screen so it can be restored on exit. ;
- ;------------------------------------------------------------------;
-
- STORE_SCREEN: MOV LINE_COUNT,25 ;25 lines to save.
- MOV DX,STATUS_REG ;Retrieve status register.
- MOV AX,SCREEN_SEG ;Point to screen buffer.
- MOV DS,AX
- PUSH CS ;Point to storage segment.
- POP ES
- XOR SI,SI ;Top left corner.
- MOV DI,OFFSET SCREEN_BUFFER ;Point to storage offset.
-
- NEXT_LINE1: MOV BP,ES:CRT_COLS ;Retrieve screen columns.
- MOV CX,80 ;Save maximum of 80 columns.
-
- HORZ_RET1: IN AL,DX ;Get status.
- TEST AL,1 ;Is it low?
- JNZ HORZ_RET1 ;If no, wait until it is.
- CLI ;No more interrupts.
-
- WAIT1: IN AL,DX ;Get status
- TEST AL,1 ;Is it high?
- JZ WAIT1 ;If no, wait until it is.
- LODSW ;Retrieve a word.
- STI ;Interrupts back on.
- STOSW ;Store the character/attribute.
-
- DEC BP ;Decrement screen column count.
- JZ SHORT_COLS1 ;Was it less than 80?
- LOOP HORZ_RET1 ;If no, loop until row done.
-
- SHL BP,1 ;Convert balance to a word.
- ADD SI,BP ;Add to screen offset.
- JMP SHORT CK_LINES1
-
- SHORT_COLS1: DEC CX ;Adjust balance.
- SHL CX,1 ;Convert to a word.
- ADD DI,CX ;Add to storage offset.
-
- CK_LINES1: DEC ES:LINE_COUNT ;Do all 25 lines.
- JNZ NEXT_LINE1
-
- PUSH CS ;Restore data segment.
- POP DS
- RET ;Return.
-
- ;---------------------------------------------;
- ; This subroutine writes to the screen buffer ;
- ;---------------------------------------------;
-
- WRITE_SCREEN: MOV LINE_COUNT,25 ;25 lines to save.
- MOV DX,STATUS_REG ;Retrieve status register.
- MOV AX,SCREEN_SEG ;Point to screen buffer.
- MOV ES,AX
- XOR DI,DI ;Top left corner.
-
- NEXT_LINE2: MOV BP,CRT_COLS ;Retrieve screen columns.
- MOV CX,80 ;Write maximum of 80 columns.
-
- NEXT_BYTE: LODSW ;Get a byte.
- MOV BX,AX ;Store it in AX.
-
- HORZ_RET2: IN AL,DX ;Get status.
- TEST AL,1 ;Is it low?
- JNZ HORZ_RET2 ;If no, wait until it is.
- CLI ;No more interrupts.
-
- WAIT2: IN AL,DX ;Get status.
- TEST AL,1 ;Is it high?
- JZ WAIT2 ;If no, wait until it is.
- MOV AX,BX ;Retrieve the word
- STOSW ; and store it.
- STI ;Interrupts back on.
-
- DEC BP ;Decrement screen column count.
- JZ SHORT_COLS2 ;Was it less than 80?
- LOOP NEXT_BYTE ;If no, loop until row done.
-
- SHL BP,1 ;Convert balance to a word.
- ADD DI,BP ;Add to storage offset.
- JMP SHORT CK_LINES2
-
- SHORT_COLS2: DEC CX ;Adjust balance.
- SHL CX,1 ;Convert to a word.
- ADD SI,CX ;Add to screen offset.
-
- CK_LINES2: DEC LINE_COUNT ;Do all 25 lines.
- JNZ NEXT_LINE2
- RET
-
-
- SCREEN_BUFFER LABEL BYTE
- PAGE_BUFFER EQU SCREEN_BUFFER + ( 2 * 80 * 25 )
-
- CODE ENDS
- END START
-